//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <winhack.h>
#include <elasys_server.h>
#include <elapi.h>
#include <stdio.h>
#include <console.h>
#include <filedisk.h>

static IDeviceDriver *g_pSdFileDisk = NULL;
int DoInsertDisk(int argc, wchar_t **argv)
{
    ECode ec;
    if (argc < 2) {
        ec = g_pSdFileDisk->Control(FILEDISK_CONTROL_OPEN,
                                NULL_MEMORYBUF,
                                NULL,
                                NULL);
    }
    else {

        MemoryBuf_<100> ebbInData;
        ebbInData.Copy((Byte *)argv[1], (wcslen(argv[1])+1)*sizeof(wchar_t));
        ec = g_pSdFileDisk->Control(FILEDISK_CONTROL_OPEN,
                                ebbInData,
                                NULL,
                                NULL);
    }

    if (ec == E_ALREADY_EXIST) {
        printf("There already have disk inserted.\n");
        printf("Pls Remove Disk Before Insert!\n");
    }

    return 0;
}

int DoRemoveDisk(int argc, wchar_t **argv)
{
    g_pSdFileDisk->Control(FILEDISK_CONTROL_CLOSE,
                            NULL_MEMORYBUF,
                            NULL,
                            NULL);
    return 0;
}

int Dotestinsert(int argc, wchar_t **argv)
{
    int temp = (int)*argv[1];
    for (int i = 0; i < 5; i++) {
        temp = i%2;
        if (temp == 0) {
            DoInsertDisk(argc, argv);
        }
        else {
            DoRemoveDisk(argc, argv);
        }
    }
    return 0;
}

int DotestDisk(int argc, wchar_t **argv)
{
    ECode ec;
    int count = 0;
    IDiskManager *pDiskMgr = NULL;

    while (pDiskMgr == NULL) {
        ec = _CSystem_FindRunningObject(L"diskmgr", (PInterface *)&pDiskMgr);
        if (FAILED(ec)) {
            if (count < 10) {
                _CThread_Sleep(100, NULL);
                count++;
            }
            else {
                wprintf(L"MiniSD: Can not find diskmgr service!\n");
                return -1;
            }
        }
    }
#define DISKINDEX L'N'
    int iDisk = DISKINDEX- L'A' + 1;
    WStringBuf_ <20> esbServiceName;
    if (FAILED(pDiskMgr->OpenDisk(iDisk, &esbServiceName))) {
        wprintf(L"Can not open disk\n");
        pDiskMgr->Release();
        return -1;
    }
    IBasicFileSystem *pBFileSystem;
    IBasicDirectory   *piRoot;
    IWStringEnumerator* piEntryNameEnumerator;
    _CSystem_FindRunningObject(esbServiceName, (PInterface *)&pBFileSystem);
    pBFileSystem->GetRoot (&piRoot);
    piRoot->GetDirEntries (&piEntryNameEnumerator);
    WStringBuf_<100> esbbuf;
    piEntryNameEnumerator->Reset();
	Boolean succeeded;
    piEntryNameEnumerator->MoveNext(&succeeded);
	while(succeeded) {
        piEntryNameEnumerator->Current(&esbbuf);
        wprintf(L"DTEST file dir name:%s\n",(wchar_t*) esbbuf);
        piEntryNameEnumerator->MoveNext(&succeeded);
    }
    piEntryNameEnumerator->Release();
    if (FAILED(pDiskMgr->CloseDisk(iDisk))) {
        wprintf(L"Can not close disk\n");
        pDiskMgr->Release();
        return -1;
    }
    pDiskMgr->Release();
    return 0;
}

ConfigConsoleCmd g_FilediskCommands[] =  {
    {                                                /* CMDS_LOAD   */
        L"insert", DoInsertDisk,
        L"insert        - Inset a virtual disk to emulator",
        L"insert:       Inset a virtual disk to emulator. Defualt disk name is \"disk.rom\"\nFormat:      insert [diskname]"
    },
    {                                                /* CMDS_LOAD   */
        L"remove", DoRemoveDisk,
        L"remove        - Remove a virtual disk from emulator",
        L"remove:       Remove a virtual disk from emulator.\nFormat:       remove"
    },
    {                                                /* CMDS_LOAD   */
        L"dtest", DotestDisk,
        L"dtest        - test disk insert",
        L"dtest:       test disk insert.\nFormat:       dtest"
    },
    {                                                /* CMDS_LOAD   */
        L"dtesti", Dotestinsert,
        L"dtesti        - test disk insert",
        L"dtesti:       test disk repeat insert.\nFormat:       dtest"
    },    {
        NULL, NULL, NULL, NULL
    }
};

ECode InitSDEvent(void)
{

    ECode ec;
    //Get Removable filedisk device driver
    ec = _CSystem_FindRunningObject(L"device:filedisk", (PInterface *)&g_pSdFileDisk);
    if (FAILED(ec)) {
        wprintf(L"MiniSD: Can not find filedisk service!\n");
        return ec;
    }
    assert(g_pSdFileDisk != NULL);

    //Register SD commands, Emulate sd insert/remove event
    for (int i = 0; NULL != g_FilediskCommands[i].pwszCmdName; i++) {
        ec = _SysRegisterCommand(&g_FilediskCommands[i]);
        if (FAILED(ec))
            return ec;
    }
    return NOERROR;
}
